#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <cstring>

#include "SerCom.h"
#include "CmdHandler.h"

using namespace std;

void signalHandler( int signum ) {
    if( signum == SIGINT ) {
        SerCom::get()->close();
        exit( 0 );
    }
}


void exec( int cmdNum )
{
    switch( cmdNum ) {
    case 0: {
        std::string result = CmdHandler::readBatteryVoltage();
        std::cout << "Battery Voltage  : " << result
                  << std::endl;
        break;
    }
    case 1: {
        std::string result = CmdHandler::readRaspiVoltage();
        std::cout << "Raspi Voltage    : " << result
                  << std::endl;
        break;
    }
    case 2: {
        std::string result = CmdHandler::readHubVoltage();
        std::cout << "USB Hub Voltage  : " << result
                  << std::endl;
        break;
    }
    case 3: {
        bool result = CmdHandler::isCharging();
        std::cout << "Charging         : " << ( result ? "Yes" : "No" )
                  << std::endl;

        break;
    }
    case 4: {
        CmdHandler::ChargingMode mode = CmdHandler::readChargeMode();
        std::string result = "Auto Charging";
        if( mode == CmdHandler::ChargingMode::Always ) {
            result = "Forced Charging";
        }
        else if( mode == CmdHandler::ChargingMode::Never ) {
            result = "Charging Disabled";
        }
        std::cout << "Charging Mode    : " << result << std::endl;
        break;
    }
    }
}

void interactive()
{
    std::string cmd;
    while( true ) {
        std::cout << "Command: ";
        std::cin >> cmd;
        if( cmd == "all" ) {
            exec( 0 );
            exec( 1 );
            exec( 2 );
            exec( 3 );
            exec( 4 );
        }
        else if( cmd == "vbat" ) {
            exec( 0 );
        }
        else if( cmd == "vraspi" ) {
            exec( 1 );
        }
        else if( cmd == "vhub" ) {
            exec( 2 );
        }
        else if( cmd == "ischarging" ) {
            exec( 3 );
        }
        else if( cmd == "cmode" ) {

            exec( 4 );
        }
        else if( cmd == "fcharge" ) {
            CmdHandler::setChargingModel( CmdHandler::ChargingMode::Always );
        }
        else if( cmd == "ncharge" ) {
            CmdHandler::setChargingModel( CmdHandler::ChargingMode::Never );
        }
        else if( cmd == "acharge" ) {
            CmdHandler::setChargingModel( CmdHandler::ChargingMode::Auto );
        }
        else if( cmd == "exit" ) {
            return;
        }
        else {
            std::cout << "----- i n v a l i d -----" << std::endl;
        }
        std::cout << std::endl << std::endl;
    }
}

int main( int argc, char** argv )
{
    signal( SIGINT, &signalHandler ); 
    std::cout << "Waiting for serial port ......." << std::endl << std::endl;
    sleep( 8 );
    -- argc;
    if( argc > 2 ) {
        if( ! SerCom::get()->init( argv[ 2 ] )) {
            std::cout << "Init Failed. Aborting" << std::endl;
            return -1;
        }
    }
    else {
        if( ! SerCom::get()->init( "/dev/ttyUSB0" )) {
            std::cout << "Init Failed. Aborting" << std::endl;
            return -1;
        }
    }
    if( argc == 0 || ! std::strcmp( argv[ 1 ], "loop" )) {
        int orbitr = 0;
        while( true ) {
            exec( orbitr );
            orbitr = ( orbitr + 1 ) % 6;
            if( orbitr == 0 ) {
                std::cout << "---------------------------------- " << std::endl;
                if( argc > 0 && ! std::strcmp( argv[ 1 ], "loop" )) {
                    sleep( 1 );
                }
                else {
                    break;
                }
            }
        }
    }
    else {
        if( ! std::strcmp( argv[ 1 ], "int" )) {
            interactive();
        }
        else if( ! std::strcmp( argv[ 1 ], "fcharge" )) {
            CmdHandler::setChargingModel( CmdHandler::ChargingMode::Always );
        }
        else if( ! std::strcmp( argv[ 1 ], "acharge" )) {
            CmdHandler::setChargingModel( CmdHandler::ChargingMode::Auto );
        }
        else if( ! std::strcmp( argv[ 1 ], "ncharge" )) {
            CmdHandler::setChargingModel( CmdHandler::ChargingMode::Never );
        }
        else if( ! std::strcmp( argv[ 1 ], "vbat" ) ) {
            std::string result = CmdHandler::readBatteryVoltage();
            std::cout << "Battery Voltage  : " << result
                      << std::endl;
        }
        else if( ! std::strcmp( argv[ 1 ], "vraspi" ) ) {
            std::string result = CmdHandler::readRaspiVoltage();
            std::cout << "Raspi Voltage    : " << result
                      << std::endl;
        }
        else if( ! std::strcmp( argv[ 1 ], "vhub" ) ) {
            std::string result = CmdHandler::readHubVoltage();
            std::cout << "USB Hub Voltage  : " << result
                      << std::endl;
        }
        else if( ! std::strcmp( argv[ 1 ], "ischarging" ) ) {
            bool result = CmdHandler::isCharging();
            std::cout << "Charging         : " << ( result ? "Yes" : "No" )
                      << std::endl;

        }
        else if( ! std::strcmp( argv[ 1 ], "cmode" ) ) {
            CmdHandler::ChargingMode mode = CmdHandler::readChargeMode();
            std::string result = "Auto Chargin";
            if( mode == CmdHandler::ChargingMode::Always ) {
                result = "Forced Charging";
            }
            else if( mode == CmdHandler::ChargingMode::Never ) {
                result = "Charging Disabled";
            }
            std::cout << "Charging Mode    : " << result << std::endl;
        }
     }
     SerCom::get()->close();
}




